package cn.tpshion.task.server;

import cn.tpshion.task.common.MsgAction;
import cn.tpshion.task.config.support.GoTaskProperties;
import cn.tpshion.task.data.ConnData;
import cn.tpshion.task.data.MsgData;
import cn.tpshion.task.task.MsgHandler;
import cn.tpshion.task.task.MsgHandlerFactory;
import com.alibaba.fastjson.JSON;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Slf4j
@ChannelHandler.Sharable
public class ClientHandler extends SimpleChannelInboundHandler<String> {

    private final GoTaskProperties properties;

    private final ThreadPoolTaskExecutor goMsgExecutor;

    private final MsgHandlerFactory msgHandlerFactory;

    public ClientHandler(GoTaskProperties properties, MsgHandlerFactory msgHandlerFactory, ThreadPoolTaskExecutor goMsgExecutor) {
        this.properties = properties;
        this.msgHandlerFactory = msgHandlerFactory;
        this.goMsgExecutor = goMsgExecutor;
    }

    /**
     * 连接建立后发送消息
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ConnData connData = new ConnData();
        connData.setName(properties.getName());
        connData.setTaskGroup(properties.getTaskGroup());
        connData.setUsername(properties.getUsername());
        connData.setPassword(properties.getPassword());
        String msgData = MsgData.ofJson(MsgAction.CONN, JSON.toJSONString(connData));
        ctx.writeAndFlush(msgData);
        log.info("conn task server msgData:{}", msgData);
    }

    /**
     * 接收服务器响应
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        goMsgExecutor.execute(() -> {
            log.info("Received response from server: {}", msg);
            MsgData msgData = JSON.parseObject(msg, MsgData.class);
            if (MsgAction.AUTH_FAIL.getAction().equals(msgData.getAction())) {
                log.error("task server conn error:{}", msgData.getData());
                return;
            }
            MsgHandler handler = msgHandlerFactory.getHandler(msgData.getAction());
            if (Objects.isNull(handler)) {
                return;
            }
            handler.handler(ctx, msgData);
        });
    }

    /**
     * 异常处理
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("Client error: {}", cause.getMessage());
        ctx.close();
    }


}
